package com.yima.baseproj.security;

import cn.hutool.core.util.StrUtil;
import com.yima.baseproj.config.redis.RedisUtil;
import com.yima.baseproj.security.model.LoginClientEnum;
import com.yima.baseproj.security.model.UserLoginAuthModel;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * 认证相关配置项（注意这里的配置项一般都是加到配置文件上的）
 * @Author 一码
 * @createDate 2023/4/1 09:00
 * @contact 1424529270@qq.com
 */
@Component
@Data
public class SecurityUtil {

    public static final String HEADER_TOKEN = "authorization";//token参数头
    public static final String HEADER_CLIENT = "client";//客户端
    public static final String BEARER = "Bearer_";//Token 的开头部分

    public static String springProfilesActive = "local";//激活配置
    public static Boolean weappTestEnable = false;//前端测试启动
    public static String weappTestUserId = "";//前端测试账号

    @Value("${spring.profiles.active}")
    public void springProfilesActive(String active){
        this.springProfilesActive = active;
    }
    @Value("${weapp.test.enable}")
    public void securityIsTestUser(String isTestUser){
        if(StrUtil.isNotBlank(isTestUser)){
            if("true".equals(isTestUser)){
                this.weappTestEnable = false;
            }
        }
    }
    @Value("${weapp.test.userId}")
    public void securityTestUserId(String testUserId){
        this.weappTestUserId = testUserId;
    }

    /**
     * 获取客户端
     * @return
     */
    public static String getClient(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String client = request.getHeader(SecurityUtil.HEADER_CLIENT);
        if(StrUtil.isNotBlank(client)){
            client = client.replace("-","_");
        }
        return client;
    }

    /**
     * 获取用户id
     * @return
     */
    public static String getUserId(){
        String client = getClient();

        if(!SecurityUtil.weappTestEnable.booleanValue() || LoginClientEnum.admin.isSame(client)){
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if(authentication instanceof UsernamePasswordAuthenticationToken){
                UsernamePasswordAuthenticationToken jwtAuthenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
                if(jwtAuthenticationToken == null){
                    return "";
                }

                UserLoginAuthModel userLoginAuthModel = (UserLoginAuthModel)jwtAuthenticationToken.getPrincipal();
                return userLoginAuthModel.getUserId();
            }else{
                return "";
            }
        }else{
            return SecurityUtil.weappTestUserId;
        }
    }

    /**
     * token-redis 设置
     * @param userId
     * @param value
     * @return
     */
    public static void setTokenToRedis(String client,String userId,Object value){
        //设置普通存储
        RedisUtil.setNormalKey(getTokenRedisKey(client,userId),value);
        //设置过期时间
//        RedisUtil.setNormalKey(getTokenRedisKey(client,userId),value, 2L, TimeUnit.HOURS);
    }

    /**
     * 删除缓存
     * @param client
     * @param userId
     */
    public static void delTokenToRedis(String client, String userId) {
        RedisUtil.deleteKey(getTokenRedisKey(client,userId));
    }

    /**
     * token-redis 是否存在或过期
     * @param userId
     * @return
     */
    public static Boolean isTokenToRedis(String client,String userId){
        String key = getTokenRedisKey(client,userId);
        if(RedisUtil.keyExist(key)){
            return true;
        }
        return false;
    }

    /**
     * token-redis 设置续签
     * @param userId
     * @return
     */
    public static void setXuqianToRedis(String client,String userId){
        RedisUtil.setKeyExp(getTokenRedisKey(client,userId),2L, TimeUnit.HOURS);
    }

    /**
     * token-redis 获取
     * @param userId
     * @return
     */
    public static <T> T getTokenToRedis(String client,String userId){
        return RedisUtil.<T>getNormalValue(getTokenRedisKey(client,userId));
    }

    /**
     * redis-token 获取key
     * @param userId
     * @return
     */
    public static String getTokenRedisKey(String client,String userId){
        String key = String.format("LOGIN:%s:%s",client,userId);
        return key;
    }
}